// 检测任务的标注结果
import labelDef from './Def';
import LabelConfig from '@/js/models/LabelConfig';
import LabelDetection from '../detection/Label';
import LabelStorageLocal from '@/js/models/LabelStorageLocal';
import { getCurrentTime } from '@/js/utils/baseUtils';
import { newKeypointsFObject, getKeypointFill, setFObjectEditable } from '@/js/utils/FabricControls';
import { getImageCoords, getCanvasCoords } from '@/js/utils/imageUtils';

export default class LabelKeypoint extends LabelDetection {
    // 构造函数
    constructor(label_format) {
        super(label_format);
        this.labels_geom_keypoints = [];
    }

    ///====================以下定义geom显示相关的处理函数========================
    // 在canvas中渲染结果
    bindCanvas(canvas, image, label_tools) {
        // console.log('bindCanvas canvas = ', canvas);
        super.bindCanvas(canvas, image, label_tools);

        // 绘制关键点相关的逻辑
        for (let i = 0; i < this.labels.length; i++) {
            let label = this.labels[i];
            if (!label) continue;
            let { back, kps, lines } = this.paintKeypoints(label);
            if (back && kps && lines) {
                this.labels_geom_keypoints[label.id] = {
                    back,
                    kps,
                    lines
                };
                back && this.canvas.add(back);
                kps && this.canvas.add(...kps);
                lines && this.canvas.add(...lines);
            }
        }

        // 刷新显示
        this.canvas.requestRenderAll();
        return true;
    }

    paintKeypoints(label) {
        // console.log('paintKeypoints label = ', label, ', LabelStorageLocal.categories = ', LabelStorageLocal.categories);
        let category = LabelStorageLocal.categories.find((el) => el.category_id === label.data.category_id);
        let skeleton = category ? category.skeleton : null;
        if (label.data.keypoints.length == 0 || !skeleton || !this.image) {
            return { back: null, kps: null, lines: null };
        }

        // 获取当前任务的标注类别
        let keypoints = label.data.keypoints;
        let real_left = this.image.left - this.image.width / 2;
        let real_top = this.image.top - this.image.height / 2;
        const parsedKeypoints = [];
        for (let i = 0; i < keypoints.length; i += 3) {
            parsedKeypoints.push({
                x: keypoints[i] + real_left,
                y: keypoints[i + 1] + real_top,
                visibility: keypoints[i + 2], // 使用COCO可见性标记
                id: i / 3 // 关键点索引（COCO17关键点为0-16）
            });
        }

        // 创建Keypoints的Fabricjs对象
        // console.log(`keypoints = `, parsedKeypoints, `, skeleton = `, skeleton);
        let { back, kps, lines } = newKeypointsFObject(label.id, parsedKeypoints, skeleton, LabelConfig.base_config);
        this.registerObjectEvents(back);
        for (let i = 0; i < kps.length; i++) {
            this.registerObjectEvents(kps[i]);
        }
        return { back, kps, lines };
    }

    setEditableMode(editable = true) {
        super.setEditableMode(editable);
        for (let i = 0; i < this.labels_geom_keypoints.length; i++) {
            let geoms = this.labels_geom_keypoints[i];
            if (geoms) {
                // 设置半透背景不响应事件
                geoms.back && geoms.back.set({
                    selectable: editable,
                    evented: editable
                });
                // 设置keypoints不响应事件
                for (let j = 0; j < geoms.kps.length; j++) {
                    let keypoint = geoms.kps[j];
                    keypoint && keypoint.set({
                        selectable: editable,
                        evented: editable
                    });
                }
            }
        }
    }

    selectLabel(label_id, target = null) {
        // 取消选择，并根据是否有点击的具体对象，将需要选中的对象都放到selected_geoms中
        this.unselectLabel();

        // 放置待选择的对象
        let select_geoms = [];
        if (target) {
            select_geoms = [target];
        } else {
            select_geoms = [];
            let rect = this.labels_geom_rect[label_id];
            if (rect) {
                select_geoms.push(rect);
            }
            let polys = this.labels_geom_poly[label_id];
            if (polys) {
                for (let i = 0; i < polys.length; i++) {
                    let poly = polys[i];
                    select_geoms.push(poly);
                }
            }
            let kps = this.labels_geom_keypoints[label_id];
            if (kps) {
                select_geoms.push(kps.back);
            }
        }

        // 设置fabricjs的geom对象，选中的属性
        for (let i = 0; i < select_geoms.length; i++) {
            let geom = select_geoms[i];
            if (geom.data.type === 'keypoint') {
                geom.set({
                    fill: 'rgba(255,255,255,0.8)',
                    stroke: 'rgba(200,0,0,1.0)'
                });
            } else if (geom.data.type === 'keypoints_back') {
                geom.set({
                    fill: 'rgba(200,0,0,0.2)',
                    stroke: 'rgba(200,0,0,1.0)',
                    strokeWidth: 1,
                    strokeDashArray: [5, 5]
                });
            } else if (geom.data.type === 'bbox' || geom.data.type === 'segm') {
                geom.set({
                    fill: 'rgba(200,0,0,0.2)',
                    stroke: 'rgba(200,0,0,1.0)'
                });
                setFObjectEditable(geom);
            }
        }

        // 设置activateobject
        if (target) {
            this.canvas.setActiveObject(target);
        } else {
            this.canvas.setActiveObject(select_geoms[0]);
        }
        this.last_selected_geoms = select_geoms;
        this.canvas.requestRenderAll();

        // 在label_panel中选择标签对象
        this.label_panel && this.label_panel.selectLabel(label_id);
    }

    unselectLabel() {
        // 恢复keypoints Fabricobject的样式
        for (let i = 0; i < this.last_selected_geoms.length; i++) {
            let geom = this.last_selected_geoms[i];
            let config = {};
            if (geom.data.type === 'keypoint') {
                config = {
                    fill: getKeypointFill(geom.data.visibility, LabelConfig.base_config),
                    strokeWidth: LabelConfig.getConfig(`keypoint.strokeWidth`),
                    stroke: LabelConfig.getConfig(`keypoint.stroke`),
                    hasControls: false
                };
                geom.set(config);
            } else if (geom.data.type === 'keypoints_back') {
                config = {
                    fill: LabelConfig.getConfig(`keypoints_back.fill`),
                    strokeWidth: LabelConfig.getConfig(`keypoints_back.strokeWidth`),
                    stroke: LabelConfig.getConfig(`keypoints_back.stroke`),
                    hasControls: false
                };
                geom.set(config);
            } else if (geom.data.type === 'bbox' || geom.data.type === 'segm') {
                let type = geom.type;
                let config = {
                    fill: LabelConfig.getConfig(`${type}_style.fill`),
                    strokeWidth: LabelConfig.getConfig(`${type}_style.strokeWidth`),
                    stroke: LabelConfig.getConfig(`${type}_style.stroke`),
                    hasControls: false
                };
                geom.set(config);
            }
        }
        this.last_selected_geoms = [];

        // 在label_panel中取消选择panel
        this.label_panel && this.label_panel.selectLabel(-1);
    }

    onLabelModified(event) {
        // console.log('LabelKeypoint::onLabelModified event = ', event);
        // 读取fabricjs更新后的信息
        let label_id = event.target.label_id;
        let geom = event.target;
        let points = null;
        let update_info = {
            id: label_id
        };
        let kpId = 0;
        let kps = this.labels[label_id].data.keypoints;
        if (geom && geom.data.type == 'keypoint') {
            points = [{ x: geom.left, y: geom.top }];
            points = getImageCoords(this.image, points);
            kpId = geom.data.cocoId - 1;
            kps[kpId * 3] = Math.round(points[0].x);
            kps[kpId * 3 + 1] = Math.round(points[0].y);
            // 暂时未改变keypoint的可见属性，只是调整位置
            update_info['keypoints'] = kps;
        } else if (geom && geom.data.type == 'keypoints_back') {
            let geoms = this.labels_geom_keypoints[label_id].kps;
            for (let i = 0; i < geoms.length; i++) {
                kpId = geoms[i].data.cocoId - 1;
                points = [{ x: geoms[i].left, y: geoms[i].top }];
                points = getImageCoords(this.image, points);
                kps[kpId * 3] = Math.round(points[0].x);
                kps[kpId * 3 + 1] = Math.round(points[0].y);
            }
            update_info['keypoints'] = kps;
        }

        // console.log('update_info = ', update_info);
        // 更新数据中存储的信息
        this.updateLabel(update_info);

        // 更新父类的modified函数
        super.onLabelModified(event);
    }

    ///========================以下定义数据相关的处理函数========================
    // 新增标注结果
    addLabel(data) {
        console.log('LabelKeypoint addLabel data = ', data);
        this.labels[data.id] = this.labelOfBase(data.id, 'vision:keypoint', labelDef(data));
        console.log('this.labels[data.id] = ', this.labels[data.id]);
        this.saved = false;
        return true;
    }

    // 更新对应的labelid信息，可以更新poly或者text文本
    updateLabel(data) {
        // console.log(`LabelKeypoint::updateLabel data = `, data);
        let label_id = data.id;
        if (label_id in this.labels) {
            let label = this.labels[label_id];
            if (label) {
                for (let key in data) {
                    if (key === 'id') continue;
                    label.data[key] = data[key];
                }
                label.score = 1.0;
                label.timestamp = getCurrentTime();
                this.saved = false;
            }
            return true;
        } else {
            return false;
        }
    }

    deleteLabel(label_id) {
        // 删除当前构建keypoints几何
        if (this.canvas && label_id in this.labels_geom_keypoints) {
            let { back, kps, lines } = this.labels_geom_keypoints[label_id];
            back && this.canvas.remove(back);
            for (let i = 0; i < kps.length; i++) {
                kps[i] && this.canvas.remove(kps[i]);
            }
            for (let i = 0; i < lines.length; i++) {
                lines[i] && this.canvas.remove(lines[i]);
            }
            this.labels_geom_keypoints[label_id] = null;
        }

        // 删除父类的几何对象
        super.deleteLabel(label_id);
    }

    fromJson(json_data) {
        // console.log('LabelKeypoint::fromJson json_data = ', json_data);
        this.labels = [];
        for (let i = 0; i < json_data.length; i++) {
            let data = json_data[i];
            this.labels[data.id] = this.labelOfBase(data.id, 'vision:keypoint', data);
        }
    }
}
